

#include <iostream>
#include <vector>
#include <boost/spirit.hpp>
#include <boost/spirit/include/phoenix.hpp>
using namespace std;
using namespace boost::spirit;
using namespace phoenix;



bool spirit_parase_str(const char *szExp)
{
    //为rule准备一个val变量，类型为double
    //准确地说：是一个phoenix类(这里的member1)，它和其它phoenix类组成lambda表达式，在lambda中可以把它看成是一个double。
    struct calc_closure : boost::spirit::closure<calc_closure, double>
    {
        member1 val;
    };

    //定义ContextT策略为calc_closure::context_t
    rule<phrase_scanner_t, calc_closure::context_t> sub_exp , term_exp , math_exp , rela_exp,exp;
    //直接使用phoenix的lambda表达式作为Actor
    sub_exp = real_p[sub_exp.val = arg1] | ('(' >> exp[sub_exp.val = arg1] >> ')');
    term_exp   = sub_exp[term_exp.val = arg1] >> *(('*' >> sub_exp[term_exp.val *= arg1]) | ('/' >> sub_exp[term_exp.val /= arg1]));
    math_exp    = term_exp[math_exp.val = arg1] >> *(('+' >> term_exp[math_exp.val += arg1]) | ('-' >> term_exp[math_exp.val -= arg1]));
    rela_exp   = math_exp[rela_exp.val = arg1] >> *(('>' >> math_exp[rela_exp.val = rela_exp.val>arg1])
                                                   | ('<' >> math_exp[rela_exp.val = rela_exp.val<arg1])
                                                   | (">=" >> math_exp[rela_exp.val = rela_exp.val>=arg1])
                                                   | ("<=" >> math_exp[rela_exp.val = rela_exp.val<=arg1])
                                                   | ("!=" >> math_exp[rela_exp.val = rela_exp.val!=arg1])
                                                   | ("==" >> math_exp[rela_exp.val = rela_exp.val==arg1]));
    exp    = rela_exp[exp.val = arg1] >> *(("||" >> rela_exp[exp.val = exp.val || arg1] )
                                           | ("&&" >> rela_exp[exp.val = exp.val && arg1]));

    double result;
    parse_info<> r = parse( szExp , exp[assign_a(result)], space_p);
    cout << szExp;
    if(r.full)
    {
        //成功，得到结果
        cout << " = " << result << endl;
        return  true;
    }
    else
    {
        //失败，显示错误位置
        cout << "parase fail: " << endl << string(r.stop - szExp, ' ') << '^' << endl;
        return false;
    }
}

int main()
{


    {
        // 解析演示：
        rule<phrase_scanner_t> sub_exp , rela_exp , term_exp , math_exp ,exp;
        sub_exp = real_p | ('(' >> exp >> ')');
        term_exp   = sub_exp >> *(('*' >> sub_exp) | ('/' >> sub_exp));
        math_exp    = term_exp >> *(('+' >> term_exp) | ('-' >> term_exp));
        rela_exp = math_exp >> *(('<' >> math_exp) | ('>' >> math_exp)
                                | ("<=" >> math_exp) | (">=" >> math_exp)
                                | ("==" >> math_exp) | ("!=" >> math_exp));
        exp    = rela_exp >> *(("||" >> rela_exp) | ("&&" >> rela_exp));

        const char *szExp = "( 1 >2+4) || ( (0==9) && 1>=(8/9) )";
        parse_info<> r = parse( szExp , exp, space_p);

        cout << "parsed " << (r.full?"successful":"failed") << endl;


    }


    spirit_parase_str("1 || ( 0 && 1 )");
    spirit_parase_str("1 && ( 0 && 1 ) || 0 || 1 && (1<8)");
    spirit_parase_str("(1==7)");
    spirit_parase_str("(1<=7)");
    spirit_parase_str("(1>=7)");
    spirit_parase_str("(1!=7)");
    spirit_parase_str("(1!=7) && (1<=7)");
    spirit_parase_str("1 || ( (0<9) && 1+9 )");
    spirit_parase_str("1 || ( 9*7 && 8-7 )");
    spirit_parase_str("1 && ( 9*7 && 8-9 )");
    spirit_parase_str("(8-9)*77/2+4");
    return 0;
}
